package com.example.demo.jackson;

import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JacksonViewConfiguration {

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer objectMapperCustomizer() {
        return builder -> {
            // jacksonViewAnnotationIntrospector() 强制使用过滤器后
            // SimpleFilterProvider#findPropertyFilter 找不到过滤器且没有默认过滤器会抛出异常
            // 这里为 SimpleFilterProvider 设置默认过滤器
            // PS：也可以选择通过 new SimpleFilterProvider().setFailOnUnknownId(false) 来关闭找不到过滤器异常
            FilterProvider provider = new SimpleFilterProvider().setDefaultFilter(SimpleBeanPropertyFilter.serializeAll());
            builder.filters(provider);

            builder.annotationIntrospector(jacksonViewAnnotationIntrospector());
        };
    }

    /**
     * 由于 <code>@JsonFilter</code> 注解不怎么好用<br>
     * 这里强制 Jackson 在序列化时寻找 ID 为 <code>JacksonViewResponseBodyAdvice.JACKSON_VIEW_FILTER_ID</code> 的过滤器
     */
    private AnnotationIntrospector jacksonViewAnnotationIntrospector() {
        return new JacksonAnnotationIntrospector() {

            @Override
            public Object findFilterId(Annotated a) {
                return JacksonViewResponseBodyAdvice.JACKSON_VIEW_FILTER_ID;
            }

        };
    }

}
